View Javadoc
1   package edu.jiangxin.apktoolbox.android.i18n;
2   
3   import edu.jiangxin.apktoolbox.swing.extend.EasyPanel;
4   import edu.jiangxin.apktoolbox.swing.extend.listener.SelectDirectoryListener;
5   import edu.jiangxin.apktoolbox.utils.Constants;
6   import edu.jiangxin.apktoolbox.utils.SAXBuilderHelper;
7   import org.apache.commons.collections4.CollectionUtils;
8   import org.apache.commons.lang3.StringUtils;
9   import org.jdom2.Document;
10  import org.jdom2.Element;
11  import org.jdom2.JDOMException;
12  import org.jdom2.input.SAXBuilder;
13  
14  import javax.swing.*;
15  import java.awt.*;
16  import java.awt.event.ActionEvent;
17  import java.awt.event.ActionListener;
18  import java.io.File;
19  import java.io.FileFilter;
20  import java.io.IOException;
21  import java.io.Serial;
22  import java.util.ArrayList;
23  import java.util.List;
24  
25  /**
26   * @author jiangxin
27   * @author 2019-04-12
28   *
29   */
30  public class I18nFindLongestPanel extends EasyPanel {
31      @Serial
32      private static final long serialVersionUID = 1L;
33  
34      private final transient List<I18nInfo> infos = new ArrayList<>();
35  
36      private JTextField srcTextField;
37  
38      private JTextField itemTextField;
39  
40      public I18nFindLongestPanel() throws HeadlessException {
41          super();
42      }
43  
44      @Override
45      public void initUI() {
46          BoxLayout boxLayout = new BoxLayout(this, BoxLayout.Y_AXIS);
47          setLayout(boxLayout);
48  
49          createSourcePanel();
50          add(Box.createVerticalStrut(Constants.DEFAULT_Y_BORDER));
51          createItemPanel();
52          add(Box.createVerticalStrut(Constants.DEFAULT_Y_BORDER));
53          createOperationPanel();
54      }
55  
56      private void createOperationPanel() {
57          JPanel operationPanel = new JPanel();
58          operationPanel.setLayout(new BoxLayout(operationPanel, BoxLayout.X_AXIS));
59          add(operationPanel);
60  
61          JButton findButton = new JButton(bundle.getString("android.i18n.longest.find"));
62          findButton.addActionListener(new ActionListener() {
63              @Override
64              public void actionPerformed(ActionEvent e) {
65                  infos.clear();
66  
67                  String srcPath = checkAndGetDirContent(srcTextField, "android.i18n.longest.src.dir", "Source directory is invalid");
68                  if (StringUtils.isEmpty(srcPath)) {
69                      return;
70                  }
71  
72                  String item = checkAndGetStringContent(itemTextField, "android.i18n.longest.items", "Item is empty");
73                  if (StringUtils.isEmpty(item)) {
74                      return;
75                  }
76  
77                  sort(srcPath, itemTextField.getText());
78                  if (CollectionUtils.isEmpty(infos)) {
79                      Toolkit.getDefaultToolkit().beep();
80                      JOptionPane.showMessageDialog(I18nFindLongestPanel.this, "Failed, please see the log", "ERROR",
81                              JOptionPane.ERROR_MESSAGE);
82                  } else {
83                      I18nInfo info = infos.get(0);
84                      StringBuilder sb = new StringBuilder();
85                      sb.append("length: ").append(info.length).append(System.lineSeparator())
86                              .append("text: ").append(info.text).append(System.lineSeparator())
87                              .append("path: ").append(info.path);
88                      Toolkit.getDefaultToolkit().beep();
89                      JOptionPane.showMessageDialog(I18nFindLongestPanel.this, sb.toString(), "INFO",
90                              JOptionPane.INFORMATION_MESSAGE);
91                  }
92  
93              }
94          });
95  
96          operationPanel.add(findButton);
97      }
98  
99      private void createItemPanel() {
100         JPanel itemPanel = new JPanel();
101         itemPanel.setLayout(new BoxLayout(itemPanel, BoxLayout.X_AXIS));
102         add(itemPanel);
103         
104         itemTextField = new JTextField();
105         itemTextField.setText(conf.getString("android.i18n.longest.items"));
106 
107         JLabel itemLabel = new JLabel("Items");
108 
109         itemPanel.add(itemTextField);
110         itemPanel.add(Box.createHorizontalGlue());
111         itemPanel.add(itemLabel);
112     }
113 
114     private void createSourcePanel() {
115         JPanel sourcePanel = new JPanel();
116         sourcePanel.setLayout(new BoxLayout(sourcePanel, BoxLayout.X_AXIS));
117         add(sourcePanel);
118         
119         srcTextField = new JTextField();
120         srcTextField.setText(conf.getString("android.i18n.longest.src.dir"));
121 
122         JButton srcButton = new JButton("Source Directory");
123         srcButton.addActionListener(new SelectDirectoryListener("select a directory", srcTextField));
124 
125         sourcePanel.add(srcTextField);
126         sourcePanel.add(Box.createHorizontalGlue());
127         sourcePanel.add(srcButton);
128     }
129 
130     private String getCanonicalPath(File file) {
131         if (file == null) {
132             logger.error("file is null");
133             return null;
134         }
135         try {
136             return file.getCanonicalPath();
137         } catch (IOException e) {
138             logger.error("getCanonicalPath failed: {}", file.getAbsolutePath());
139             return null;
140         }
141     }
142 
143     private void sort(String sourceBaseStr, String itemName) {
144         File[] sourceParentFiles = new File(sourceBaseStr).listFiles(new FileFilter() {
145             @Override
146             public boolean accept(File pathname) {
147                 return pathname.getName().startsWith("values");
148             }
149         });
150         if (sourceParentFiles == null) {
151             logger.error("None valid directory found");
152             return;
153         }
154         for (File sourceParentFile : sourceParentFiles) {
155             File sourceFile = new File(sourceParentFile, "strings.xml");
156             if (sourceFile.exists()) {
157                 SAXBuilder builder = new SAXBuilder();
158                 SAXBuilderHelper.setSecurityFeatures(builder);
159                 Document sourceDoc;
160                 try {
161                     sourceDoc = builder.build(sourceFile);
162                 } catch (JDOMException | IOException e) {
163                     logger.error("build failed: {}", sourceFile);
164                     continue;
165                 }
166                 Element sourceRoot = sourceDoc.getRootElement();
167                 for (Element child : sourceRoot.getChildren()) {
168                     String value = child.getAttributeValue("name");
169                     if (value != null && value.equals(itemName)) {
170                         String text = child.getText();
171                         if (text != null) {
172                             I18nInfo info = new I18nInfo(getCanonicalPath(sourceFile), text, text.length());
173                             infos.add(info);
174                             break;
175                         }
176                     }
177                 }
178 
179             }
180 
181         }
182         infos.sort((o1, o2) -> o2.length - o1.length);
183 
184         logger.info(infos);
185     }
186 
187     static class I18nInfo {
188         String path;
189         String text;
190         int length;
191 
192         public I18nInfo(String path, String text, int length) {
193             this.path = path;
194             this.text = text;
195             this.length = length;
196         }
197 
198         @Override
199         public String toString() {
200             return "I18NInfo [path=" + path + ", text=" + text + ", length=" + length + "]";
201         }
202     }
203 }